use scraper::{Html, Selector};
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    const ARXIV_URL: &str = "https://arxiv.org/list/cond-mat.supr-con/recent";
    const TEST_URL: &str = "https://www.baidu.com";
    let client = reqwest::Client::builder()
        .user_agent("Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
        .build()?;
    let arxiv_html = client.get(ARXIV_URL).send().await?.text().await?;
    let arxiv_document = Html::parse_document(&arxiv_html);
    let publish_time_selector = Selector::parse("h3")?;
    let papers_selector = Selector::parse("dl")?;
    let mut publish_time_selection = arxiv_document.select(&publish_time_selector);
    let publish_time = publish_time_selection
        .next()
        .unwrap()
        .text()
        .next()
        .unwrap();
    let mut papers_table = arxiv_document.select(&papers_selector).next().unwrap();
    let article_ids_selector = Selector::parse("dt")?;
    let mut article_ids_selection = papers_table.select(&article_ids_selector);
    let papers_selector = Selector::parse("dd")?;
    let papers_selection = papers_table.select(&papers_selector);
    let mut article_ids: Vec<String> = Vec::new();
    for article_id_selection in article_ids_selection {
        let article_id = article_id_selection
            .select(&Selector::parse("span")?)
            .next()
            .unwrap()
            .select(&Selector::parse("a")?)
            .next()
            .unwrap()
            .text()
            .next()
            .unwrap();
        article_ids.push(article_id.to_string());
    }
    let mut papers: Vec<Paper> = Vec::new();
    for paper_selection in papers_selection {
        let title = paper_selection
            .select(&Selector::parse("div.list-title")?)
            .next()
            .unwrap()
            .text()
            .filter(|t| *t != "\n" && *t != "Title:")
            .next()
            .unwrap();
        println!("{:#?}", title);
    }

    Ok(())
}

struct Paper {
    article_id: String,
    title: String,
    authors: Vec<Author>,
    subjects: Vec<String>,
    publish_time: String,
}

impl Paper {
    fn new(
        article_id: String,
        title: String,
        authors: Vec<Author>,
        subjects: Vec<String>,
        publish_time: String,
    ) -> Paper {
        Paper {
            article_id,
            title,
            authors,
            subjects,
            publish_time,
        }
    }
}

struct Author {
    name: String,
}
